package cn.honglian.basic.service.impl;

import cn.honglian.basic.config.BussinessException;
import cn.honglian.basic.constant.RegisterCon;
import cn.honglian.basic.constant.WechatCon;
import cn.honglian.basic.dto.FountPhoneLoginDto;
import cn.honglian.basic.dto.LoginDto;
import cn.honglian.basic.dto.WechatDto;
import cn.honglian.basic.dto.WxBuderDto;
import cn.honglian.basic.service.LoginService;
import cn.honglian.basic.util.AjaxResult;
import cn.honglian.basic.util.HttpUtil;
import cn.honglian.basic.util.MD5Utils;
import cn.honglian.user.domain.Logininfo;
import cn.honglian.user.domain.User;
import cn.honglian.user.domain.Wxuser;
import cn.honglian.user.mapper.LogininfoMapper;
import cn.honglian.user.mapper.UserMapper;
import cn.honglian.user.mapper.WxuserMapper;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private WxuserMapper wxuserMapper;

    @Autowired
    private UserMapper userMapper;
  

    /*
        后台管理员登录
     */
    @Override
    public Map<String, Object> account(LoginDto dto) {

            // 参数校验
            Logininfo logininfo = verify(dto);
            // 返回给前端
             return getMap(logininfo );


    }
    private Logininfo verify(LoginDto dto) {
        // 判断数据库中是否存在dto
        Logininfo logininfo = logininfoMapper.findByDto(dto);
        if (null == logininfo) {
            throw new BussinessException("账号或密码错误");
        }
        // 判断数据库的密码与前端传来的密码是否一致
        String password = dto.getPassword();

        String passpara = MD5Utils.encrypByMd5(logininfo.getSalt() + password);
        if (!logininfo.getPassword().equals(passpara)) {
            throw new BussinessException("账号或密码错误");
        }
        return logininfo;
    }

    private Map<String, Object> getMap(Logininfo logininfo) {
        String  token = UUID.randomUUID().toString();
        logininfo.setPhone(null);
        logininfo.setPassword(null);
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("logininfo",logininfo);
        return map;
    }

    /*
           前台用户登录
        */
    @Override
    public Map<String, Object> accountPhone(FountPhoneLoginDto dto) {
        // 参数校验
        // 判断电话号码是否存在
        Logininfo logininfo = logininfoMapper.findByPhone(dto.getUserPhone());

        if (null==logininfo){
            throw new BussinessException("电话号码错误或电话号码不存在");
        }

        // 判断传来的验证码是否与redis中的一致
        String redisCode = (String) redisTemplate.opsForValue().get(RegisterCon.REGISTER_PHONE_LOGIN + dto.getUserPhone());
        if ( null ==redisCode || !dto.getSmsCodeValue().equals(redisCode)){
            throw new BussinessException("验证码不正确");
        }

        return getMap(logininfo);
    }

    /*
       微信登录
    */
    @Override
    public AjaxResult wechat(WechatDto dto) {
        // 校验参数
        // 根据Code获取微信接口中的token
        String tokenURL = HttpUtil.httpGet(String.format(WechatCon.WX_SECOND,WechatCon.WX_APPID,WechatCon.WX_SECRET, dto.getWxCode()));
        if (StringUtils.isBlank(tokenURL)){
            throw  new BussinessException("网络不通");
        }
        // 转成json对象
        JSONObject jsonObject = JSONObject.parseObject(tokenURL);
        // 获取token
        String token = (String) jsonObject.get("access_token");
        if (null == token){
            throw  new BussinessException("网络不通");
        }
        // 获取openid
        String  openid = (String) jsonObject.get("openid");
        Wxuser wxuser = wxuserMapper.findByopenId(openid);
        // 判断wxuser表中是否有userid，如果有则查询logininfo中是否有，如果有则是登录过，直接让他登录
        if (null!=wxuser && null!= wxuser.getUserId()){
            Logininfo logininfo = logininfoMapper.findByUsetId(wxuser.getUserId());
           return  AjaxResult.me().success(this.getMap(logininfo));
        } else {
            // 如果没登录过 则让他强制绑定手机号
            StringBuilder sb = new StringBuilder();
            sb.append("?accessToken=")
                    .append(token)
                    .append("&openId=")
                    .append(openid);
            return AjaxResult.me().fail("nowechat").setResultObj(sb.toString());
        }


    }
    /*
    微信授权
     */
    @Override
    public Map<String, Object> wechatBinder(WxBuderDto dto) {
            //参数校验
            // 判断验证码是否与redis中一致
        String code = (String) redisTemplate.opsForValue().get(RegisterCon.BInDER_PHONE_KEY + dto.getPhone());
        if (StringUtils.isBlank(code) || !dto.getVerifyCode().equals(code)) {
            throw new BussinessException("验证码不能为空或者验证码错误");
        }
            // 调用微信第三个接口
        String tokenURL = HttpUtil.httpGet(String.format(WechatCon.WX_THIRD,dto.getAccessToken(),dto.getOpenId()));
        if (StringUtils.isBlank(tokenURL)) {
            throw new BussinessException("网络繁忙");
        }
        // 获取用户的信息
        Wxuser wxuser = JSONObject.parseObject(tokenURL, Wxuser.class);
        if (null==wxuser) {
            throw new BussinessException("网络繁忙");
        }
            // 查询user表中是否有
        User user = userMapper.findByPhone(dto.getPhone());
        Logininfo logininfo = new Logininfo();
        if (null==user) {
            // 没有的话添加三张表的数据
            user = dto.getUser();

            BeanUtils.copyProperties(user,logininfo);
            logininfo.setType(1);
            logininfo.setDisable(1);
            logininfoMapper.add(logininfo);
            user.setLogininfoId(logininfo.getId());
            userMapper.add(user);

        } else{
            // 有则直接登录
          logininfo = logininfoMapper.findByUsetId(user.getId());
        }
        wxuser.setUserId(user.getId());
        wxuserMapper.add(wxuser);
        return getMap(logininfo);
    }


}
